﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using eOfficeDevManager;
using System.Data;
using Pally;
using System.Globalization;
using System.IO;

namespace eGuradDev
{ 
    enum INOUTSettings
    {
        IN,
        OUT,
        INOUT,
        INOUTF1F2
    }
    public class BioFinger:IDataInterface
    {
        Pally.oTerminal myTerminal = new Pally.oTerminal();
        DeviceHandler DeviceSetting = new DeviceHandler();
        eOfficeDevManager.eOfficeDevManager eOffDev = new eOfficeDevManager.eOfficeDevManager();                    
        int _year, _month, _day, _hour, _minute, _second;
        DateTime _dateTime;
        long _userid;
        string _inOut;
        string _strInOut;//This is used as a constant. Use an enum value
        //see above example
        //BMJO
       
        INOUTSettings _inoutSettings;

        internal INOUTSettings InoutSettings
        {
            get { return _inoutSettings; }
            set { _inoutSettings = value; }
        }
        public string StrInOut
        {
            get { return _strInOut; }
            set { _strInOut = value; }
        }
        int _status;
        bool _logFile;

        public bool LogFile
        {
            get { return _logFile; }
            set { _logFile = value; }
        }

        public bool _logDelete;

        public bool LogDelete
        {
            get { return _logDelete; }
            set { _logDelete = value; }
        }

        public DataSet DownLoadData(DataSet columnHeadings)
        {
             try
                {
                     //Is this function returns only one log at a time??
                    //Otherwise you need a loop to retrive all data
                    //Also is this function removes the retrived log from the device
                    //otherwise you will face a problem of duplicate entries
                    //BMJO
                 
                   //Sreedhanya...
                   //This function returns one log at a time.. and also removed the retrieved log from the device...
                    //byte[] bRet = (Byte[])(myTerminal.RetOldestNoACKLogB());
                    //byte[] bRet = (Byte[])(myTerminal.RetOneLog(true));
                    byte[] bRet = (Byte[])(myTerminal.RetOldestNoACKLog());
                    if (bRet.Length == 16)
                    {
                        //MessageBox.Show(bRet.ToString());
                        //Calculating date
                        _year = 2000 + Convert.ToInt32(bRet[5].ToString());
                        _month = Convert.ToInt32(bRet[4].ToString());
                        _day = Convert.ToInt32(bRet[3].ToString());
                        _hour = Convert.ToInt32(bRet[2].ToString());
                        _minute = Convert.ToInt32(bRet[1].ToString());
                        _second = Convert.ToInt32(bRet[0].ToString());
                        _dateTime = new DateTime(_year, _month, _day, _hour, _minute, _second);
                        //MessageBox.Show("DateTime: " + dateTime.ToString());
                        //String.Format("{0:G}", dateTime);
                        
                        //Calculating UserId
                        //Good job sreedanya
                        //BMJO

                        _userid = (Convert.ToInt64(bRet[13].ToString()) + (256 * Convert.ToInt64(bRet[12].ToString())) + (256 * 256 * Convert.ToInt64(bRet[11].ToString())) + (256 * 256 * 256L * Convert.ToInt64(bRet[10].ToString())));
                        //MessageBox.Show("UserId: " + _userid.ToString());

                        //Check In or Out
                        //if both in and out is setting in a single device                        
                        switch (_inoutSettings)
                        {
                            case INOUTSettings.IN:
                                {
                                    _inOut = "1";
                                    break;
                                }
                            case INOUTSettings.OUT:
                                {
                                    _inOut = "2";
                                    break;
                                }
                            case INOUTSettings.INOUT:
                                {
                                    int inOut = (int)bRet[9];
                                    if (inOut == 1)
                                        _inOut = "1";
                                    else if (inOut == 2)
                                        _inOut = "2";
                                    //if (inOut == 16)  //if Press F1 - In
                                    //    _inOut = "1";
                                    //else if (inOut == 32)  // F2 - Out
                                    //    _inOut = "2";
                                    else
                                    {
                                        //BMJO need a log write with all user deatils 
                                        //timing to show that it is wrong user entry
                                        eOffDev.LogWrite("Inout status is invalid");
                                        return columnHeadings;
                                    }
                                    break;
                                }
                            case INOUTSettings.INOUTF1F2:
                                {
                                    int inOut = (int)bRet[9];
                                    if (inOut == 16)  //if Press F1 - In
                                        _inOut = "1";
                                    else if (inOut == 32)  // F2 - Out
                                        _inOut = "2";
                                    else
                                    {
                                        //BMJO need a log write with all user deatils 
                                        //timing to show that it is wrong user entry
                                        eOffDev.LogWrite("Inout status is invalid");
                                        return columnHeadings;
                                    }
                                    break;
                                }

                        }                                              

                        //Default status is 0
                        _status = 0;

                        DataRow dr = columnHeadings.Tables[0].NewRow();
                        dr["Id"] = Convert.ToInt32(_userid.ToString());
                        dr["DateTime"] = _dateTime;
                        dr["In/Out"] = Convert.ToInt32(_inOut.ToString());
                        dr["Status"] = _status;
                        if(_logFile)
                        LogDownload(dr["Id"].ToString() + "," + dr["DateTime"].ToString() + "," + dr["In/Out"].ToString() + "," + dr["Status"].ToString());
                        eOffDev.LogWrite("LogDate: \t"+_dateTime+"\t InOut: "+_inOut+"\tUser: "+_userid);
                        columnHeadings.Tables[0].Rows.Add(dr);
                        
                    }
                }
                catch (Exception exp)
                {
                    eOffDev.LogWrite(exp.ToString());

                }
           
            return columnHeadings;
        }

        public void LogDownload(string Log)
        {
            try
            {
                string strFileName = "DownloadData.txt";
                StreamWriter sWriter = new StreamWriter(strFileName, true);
                DateTime dateTime = DateTime.Now;
                sWriter.WriteLine(Log + "\r\n");
                sWriter.Close();
                sWriter.Dispose();
            }
            catch (Exception exp)
            {
                //nothing to do proceed.
            }
        }

        public bool Init(DeviceHandler devInfo)
        {
            //read xml file and init 
            //Verify XmlDictionary for validity it can be null ??
            //BMJO

            try
            {

                if (devInfo.XmlDictionary.Values.Count != 0)
                {
                    string _value;
                    if (devInfo.XmlDictionary.TryGetValue("DeviceIP", out _value))
                        myTerminal.IPAddress = _value;
                    //What is try failed??
                    //BMJO
                    if (devInfo.XmlDictionary.TryGetValue("DevicePort", out _value))
                        myTerminal.Port = _value.ToString();
                    if (devInfo.XmlDictionary.TryGetValue("TerminalId", out _value))
                        myTerminal.TerminalID = _value;
                    string _logvalue;
                    if (devInfo.XmlDictionary.TryGetValue("LogToFile", out _logvalue))
                    {
                        if (_logvalue.ToLower() == "yes")
                            _logFile = true;
                        else
                            _logFile = false;
                    }
                    string _dlog;
                    if (devInfo.XmlDictionary.TryGetValue("DeleteLog", out _dlog))
                    {
                        if (_dlog.ToLower() == "yes")
                            _logDelete = true;
                        else
                            _logDelete = false;
                    }
                    devInfo._dLog = _logDelete;
                    string _inOutValue;
                    if (devInfo.XmlDictionary.TryGetValue("InOut", out _inOutValue))
                    {
                        if (_inOutValue.ToLower() == "in")
                        { _inoutSettings = INOUTSettings.IN; }
                        else if (_inOutValue.ToLower() == "out")
                        { _inoutSettings = INOUTSettings.OUT; }
                        else if (_inOutValue.ToLower() == "inout")
                        { _inoutSettings = INOUTSettings.INOUT; }
                        else if (_inOutValue.ToLower() == "inoutf1f2")
                        { _inoutSettings = INOUTSettings.INOUTF1F2; }
                    }

                    if (myTerminal.isAlive() == true)
                    {
                        //MessageBox.Show("Online");
                        return true;
                    }
                    else
                    {
                        //DonOt use message box use log
                        //BMJO
                        //MessageBox.Show("Connection Failed");
                        eOfficeDevManager.eOfficeDevManager eOffDev = new eOfficeDevManager.eOfficeDevManager();
                        eOffDev.LogWrite("Connection failed");
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                eOfficeDevManager.eOfficeDevManager eOffDev = new eOfficeDevManager.eOfficeDevManager();
                eOffDev.LogWrite("Init failed");
               
                return false;
            }
        }

        //This function is meant for deleting log from the device
        public bool DeleteLog(DataSet logToDelete)
        {

            try
            {
                //Sreedhanya- This function helps to delete log from the device
                byte[] bRet = (Byte[])(myTerminal.RetOneLog(true));
                if (bRet.Length == 16)
                {
                    //Sreedhanya - If it successfully deleted then it clear from dataset also
                    logToDelete.Tables[0].Rows.Clear();
                    //hi hi:):)
                    //what is this. How does this delete log from the device
                    //
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception exp)
            {
                eOfficeDevManager.eOfficeDevManager eOffDev = new eOfficeDevManager.eOfficeDevManager();
                eOffDev.LogWrite(exp.ToString());
                return false;
            }
            

        }
        public DataSet DownLoadUserData(bool newOnly)
        {
            return new DataSet();
        }

        public bool IsEventSupported()
        {
            return false;
        }
        public event EventHandler UpdateDeviceStatus;
        public event EventHandler CollectLogEvent;
        
    }
}
